package com.tensquare.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tensquare.user.dao.RoleDao;
import com.tensquare.user.dto.ReqPermission;
import com.tensquare.user.dto.ReqRole;
import com.tensquare.user.exception.ParamsException;
import com.tensquare.user.exception.RecordException;
import com.tensquare.user.pojo.TbRole;
import com.tensquare.user.pojo.TbUser;
import com.tensquare.user.service.PermissionService;
import com.tensquare.user.service.TbRoleService;
import com.tensquare.user.vo.Role;
import com.tensquare.user.vo.RoleVO;
import com.tensquare.user.vo.UserInfoResponse;
import com.tensquare.user.vo.UserVO;
import com.tensquare.util.StringHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional
public class TbRoleServiceImpl implements TbRoleService {

    @Autowired
    private RoleDao roleDao;
    @Autowired
    private PermissionService permissionService;

    @Override
    public void addRole(ReqRole reqRole) {
        QueryWrapper<TbRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", reqRole.getName());
        Integer integer = roleDao.selectCount(queryWrapper);
        if (integer > 0) {
            throw new RecordException("角色已存在");
        }
        TbRole tbRole = new TbRole();
        tbRole.setName(reqRole.getName());
        tbRole.setDes(reqRole.getDes());
        tbRole.setIsDisable(reqRole.getIsDisable());
        Date date = new Date();
        tbRole.setCreateTime(date);
        tbRole.setUpdateTime(date);
        tbRole.setIsDelete("0");
        roleDao.insert(tbRole);
        TbRole tbRole1 = roleDao.selectOne(queryWrapper);
        Integer roleId = tbRole1.getId();
        if (reqRole.getPermissions().size() != 0) {
            roleDao.addPermissionForRole(roleId, reqRole.getPermissions());
        }
    }

    @Override
    public void delRole(ArrayList<Integer> roleIds) {
        List<TbRole> roles = findList(roleIds);
        if (roles.size() == 0) {
            throw new RecordException("未找到记录");
        }
        roleDao.deleteBatchIds(roleIds);
        roleDao.deleteByRolePers(roleIds);
        roleDao.deleteByUserRole(roleIds);
//        String msg = i == 0 ? "删除成功" : "删除成功："  + roles.size() + ",失败：" + i;
    }

    @Override
    public void updateRole(Integer roleId,ArrayList<Integer> permissionIds,Map<String,Object> columnData) {
//        Integer roleId = (Integer) map.get("id");
//        ArrayList<Integer> permissions = (ArrayList<Integer>) map.get("permissions");
//        columnData.remove("id");
//        columnData.remove("permissions");
        UpdateWrapper<TbRole> wrapper = new UpdateWrapper<>();
        for (String key : columnData.keySet()) {
            wrapper.set(key, columnData.get(key));
        }
        wrapper.eq("id", roleId);
        wrapper.set("update_time", new Date());
        roleDao.update(null, wrapper);
        //删除该角色所有的权限
        roleDao.deleteByRolePer(roleId);
        //赋予该角色权限
        if (null == permissionIds || permissionIds.size() == 0){return;}
        roleDao.addPermissionForRole(roleId, permissionIds);
    }

    @Override
    public RoleVO findByPage(int offset, int limit, String roleName, String roleCode, String roleStatus, Date beginCreateDate, Date endCreateDate) {
        RoleVO roleVO = new RoleVO();
        List<Role> roles = new ArrayList<>();
        Page<TbRole> tbRolePage = new Page<>(offset, limit);
        QueryWrapper<TbRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(!StringHelper.isEmpty(roleName), "name", roleName);
        queryWrapper.like(!StringHelper.isEmpty(roleCode), "des", roleCode);
        queryWrapper.eq(!StringHelper.isEmpty(roleStatus), "is_disable", roleStatus);
        queryWrapper.between(beginCreateDate != null && endCreateDate != null, "create_time", beginCreateDate, endCreateDate);
        roleDao.selectPage(tbRolePage, queryWrapper);
        for (TbRole record : tbRolePage.getRecords()) {
            Role role = new Role();
            BeanUtils.copyProperties(record, role);
            roles.add(role);
        }
        roleVO.setRoles(roles);
        roleVO.setTotal(tbRolePage.getTotal());
        roleVO.setCurrent(tbRolePage.getCurrent());
        roleVO.setSize(tbRolePage.getSize());
        return roleVO;
    }

    @Override
    public Role findOne(Integer id) {
        TbRole tbRole = roleDao.selectById(id);
        Role role = new Role();
        BeanUtils.copyProperties(tbRole, role);
        return role;
    }

    public List<TbRole> findList(ArrayList<Integer> ids) {
        return roleDao.selectBatchIds(ids);
    }

    @Override
    public void changeDisable(String disable, Integer roleId) {
        UpdateWrapper<TbRole> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", roleId);
        updateWrapper.set("is_disable", disable);
        roleDao.update(null, updateWrapper);
    }

    @Override
    public List<Role> findBatchByRoleIds(ArrayList<Integer> roleIds) {
        List<Role> roles = new ArrayList<>();
        List<TbRole> tbRoles = roleDao.selectBatchIds(roleIds);
        for (TbRole tbRole : tbRoles) {
            Role role = new Role();
            BeanUtils.copyProperties(tbRole, role);
            roles.add(role);
        }
        return roles;
    }

    @Override
    public List<String> findColumnName() {
        return roleDao.selectColumnName("tb_role", "tensquare_user");
    }

    @Override
    public void updateRoleToUser(ArrayList<Integer> roleIds, String userId) {
        roleDao.delAllRoleToUser(userId);
        roleDao.addRolesToUser(roleIds, userId);
    }

    @Override
    public UserVO findUserByRole(Integer roleId, Integer currentPage, Integer pageSize, String nickname, String mobile) {
        int userCount = roleDao.findUserCountByRoleId(roleId, nickname, mobile);
        UserVO userVO = new UserVO();
        ArrayList<UserInfoResponse> users = new ArrayList<>();
        if (userCount == 0) {
            userVO.setUserInfo(users);
            userVO.setSize(pageSize);
            return userVO;
        }
        int flag = currentPage == 1 ? 0 : currentPage;
        int offset = flag * pageSize;
        ArrayList<TbUser> tbUsers = roleDao.findUserByRoleId(roleId, offset, pageSize, nickname, mobile);
        for (TbUser tbUser : tbUsers) {
            UserInfoResponse userInfoResponse = new UserInfoResponse();
            BeanUtils.copyProperties(tbUser, userInfoResponse);
            users.add(userInfoResponse);
        }
        userVO.setSize(users.size());
        currentPage = currentPage == 0 ? 1 : currentPage;
        userVO.setCurrent(currentPage);
        userVO.setTotal(userCount);
        userVO.setUserInfo(users);
        return userVO;
    }

    @Override
    public void delUserRoleByUserIds(Integer roleId, ArrayList<String> userIds) {
        roleDao.delUserRoleByUserIds(roleId, userIds);
    }

    @Override
    public UserVO findUserNotInRole(Integer roleId, Integer pageNum, Integer pageSize, String nickName, String mobile) {
        int userCount = roleDao.findUserCountNotInRole(roleId, nickName, mobile);
        UserVO userVO = new UserVO();
        ArrayList<UserInfoResponse> users = new ArrayList<>();
        if (userCount == 0) {
            userVO.setTotal(0);
            userVO.setUserInfo(users);
            return userVO;
        }
        int pageFlag = pageNum == 1 ? 0 : pageNum;
        ArrayList<TbUser> tbUsers = roleDao.findUserNotInRole(roleId, pageFlag, pageSize, nickName, mobile);
        for (TbUser tbUser : tbUsers) {
            UserInfoResponse user = new UserInfoResponse();
            BeanUtils.copyProperties(tbUser, user);
            users.add(user);
        }
        userVO.setTotal(userCount);
        userVO.setUserInfo(users);
        userVO.setCurrent(pageNum == 0 ? 1 : pageNum);
        userVO.setSize(users.size());
        return userVO;
    }

    @Override
    public void addRoleToUser(Integer roleId, ArrayList<String> userIds) {
        roleDao.addRoleToUsers(roleId, userIds);
    }
}
